<template>
  <div
    class="card-carousel-multi-row"
    @mouseenter="isHover = true" @mouseleave="isHover = false"
    ref="parent"
  >
    <div class="card-carousel__wrapper" :class="[modelValue?.width ? `container-content-${modelValue?.width}` : 'container-content']">
      <ClientOnly v-if="listChunck.length">
        <swiper
          ref="swiperRef"
          :modules="modules"
          :centered-slides="false"
          :speed="600"
          :slides-per-view="1"
          :slides-per-group-skip="1"
          :space-between="16"
          :loop="true"
          :breakpoints="breakpoints"
          class="swiper card-carousel__swiper"
          @slideChange="onSwiperSlideChange"
          @swiper="onSwiperReady"
        >
          <swiper-slide
            v-for="(slide, slideIdx) in listChunck"
            class="swiper-slide"
            :key="slideIdx"
          >
            <div class="row" :class="[`row-cols-${perRowChunk}`]">
              <div
                class="slide-content col"
                v-for="item in slide"
                :key="item.key || item.slug"
              >
                <!-- v-if="type == 'school'" -->
                <CardSchool
                  :componentProps="item"
                  @handleClick="handleClick"
                />
                <!-- v-if="type == 'publication'" -->
                <!-- <CardPublication
                  :componentProps="item"
                  :singleColumn="perChunk == 1"
                /> -->
              </div>
            </div>
          </swiper-slide>
        </swiper>
        <div class="mt-10 mt-md-12" v-show="showSlidesPagination">
          <SlidesPagination
            :currentIndex="currentIndex"
            @updatePage="updatePage"
            :count="listChunck.length"
            dark
          ></SlidesPagination>
        </div>
      </ClientOnly>
    </div>

    <Operate v-if="!isPreview" v-model:show="isHover" @handle-edit="showSetting = true" @handle-delete="handleDelete" @handle-copy="handleCopy" @handle-paste="handlePaste"></Operate>
  </div>

  <Setting v-if="!isPreview" v-model:show="showSetting" :data="modelValue"></Setting>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { Swiper, SwiperSlide } from 'swiper/vue'
import { Navigation, Pagination } from 'swiper/modules'
import type { Swiper as SwiperType } from 'swiper'
import 'swiper/css'
import 'swiper/css/navigation'
import 'swiper/css/pagination'
// import CardPublication from './CardPublication.vue'
import CardSchool from '@/common/CardSchool/index.vue'
import SlidesPagination from '@/common/SlidesPagination/index.vue'
import { http } from '@/utils/http'
import { randomString } from '@/utils/common'
import Operate from '@/common/Operate/index.vue'
import Setting from './setting.vue'

// 定义组件名称
defineOptions({
  name: 'CardCarouselMultiRowPublications'
})

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => {}
  },

  // 是否预览
  isPreview: {
    type: Boolean,
    default: true
  },

  website: {
    type: String,
    default: 'ywies-tx'
  },

  locale: {
    type: String,
    default: 'sc'
  }
})

const emit = defineEmits(['update:modelValue', 'handleDelete', 'handleCopy', 'handlePaste', 'handleClick', 'showLightboxVideo', 'showLightboxImage'])

const handleInit = () => {
  if (props.modelValue && props.modelValue.data) return // 有数据不用初始化
  const data = {
    id: props.modelValue?.id || randomString(),
    type: 'CardCarouselMultiRowPublications',
    width: props.modelValue?.width || '',
    api: props.modelValue?.api || '/media-library/publications?per_page=1000&page=1',
    desktopCol: 4,
    mobileCol: 2,
  }
  emit('update:modelValue', data)
} 

const isHover = ref<boolean>(false);
const showSetting = ref<boolean>(false);

const handleDelete = () => {
  emit('handleDelete', props.modelValue.id)
}

const handleCopy = () => {
  emit('handleCopy', props.modelValue)
}

const handlePaste = (type: string) => {
  emit('handlePaste', type)
}

const handleClick = (url: string) => {
  emit('handleClick', url)
}

handleInit()

const modules = [Navigation, Pagination]
const breakpoints = {
  768: {
    slidesPerView: 'auto' as any,
    slidesPerGroup: 1,
    slidesPerGroupAuto: true,
    spaceBetween: 16,
  },
  1024: {
    slidesPerView: 1,
    slidesPerGroup: 1,
    spaceBetween: 16,
  },
}

const parent = ref<HTMLElement | null>(null)
const swiperRef = ref<SwiperType | null>(null)
const currentIndex = ref(0)
const listChunck = ref<any[]>([])
const mediaList = ref<any[]>([])
const screenWidth = ref(1024)

const perChunk = computed(() => {
  return (
    (screenWidth.value >= 768 ? (screenWidth.value >= 1024 ? 4 : 3) : 3) * 2
  )
})

const perRowChunk = computed(() =>
  screenWidth.value >= 768 ? (screenWidth.value >= 1024 ? 4 : 3) : 2
)

const showSlidesPagination = computed(() => mediaList.value.length > 1)

watch(currentIndex, () => {
  const ele = parent.value
  scrollTo(ele)
})

const updateScreenWidth = () => {
  if (typeof window !== 'undefined') {
    screenWidth.value = window.innerWidth
  }
}

const getData = async () => {
  if (props.modelValue?.api) {
    const url = `${props.modelValue?.api}`
    const config = {
      headers: {
        website: `${props.website}-${props.locale}`,
      },
    }
    const { data } = await http.get(url, config)
    mediaList.value = data.data
  }
  listChuncked()
}

const listChuncked = () => {
  const result = mediaList.value.reduce((resultArray: any[], item: any, index: number) => {
    const chunkIndex = Math.floor(index / perChunk.value)
    if (!resultArray[chunkIndex]) resultArray[chunkIndex] = []
    resultArray[chunkIndex].push(item)
    return resultArray
  }, [])
  listChunck.value = result
}

const onSwiperReady = (swiper: SwiperType) => {
  swiperRef.value = swiper
}

const onSwiperSlideChange = () => {
  if (!swiperRef.value) return
  currentIndex.value = swiperRef.value.realIndex
  removeAssetsClickHandler()
  addAssetsClickHandler()
}

const updatePage = (idx: number) => {
  if (!swiperRef.value) return
  swiperRef.value.slideToLoop(idx, 600)
}

const openLightboxVideo = (item: any) => {
  if (item.video_type === 'outer') return
  const modalList = mediaList.value.filter(
    (v: any) => v.video_type !== 'outer' && v.type !== 'photo'
  )
  const modalIdx = modalList.findIndex((v: any) => {
    return v.slug === item.slug
  })
  // Emit event - replace with proper event bus or composable
  emit('showLightboxVideo', {
    idx: modalIdx,
    list: modalList,
  })
}

const openLightboxImage = (item: any) => {
  const modalList = mediaList.value.filter((v: any) => v.type === 'photo')
  const modalIdx = modalList.findIndex((v: any) => {
    return v.slug === item.slug
  })
  // Emit event - replace with proper event bus or composable
  emit('showLightboxImage', {
    idx: modalIdx,
    url: item.url,
    text: item.text || item.title,
    list: modalList,
  })
}

const getPosition = (ele: HTMLElement) => {
  const rect = ele.getBoundingClientRect()
  return {
    x: rect.left + window.pageXOffset,
    y: rect.top + window.pageYOffset
  }
}

const scrollTo = (ele: HTMLElement | null) => {
  if (!ele || typeof window === 'undefined') return
  const fixPx = screenWidth.value >= 1024 ? 170 : 150
  const top = getPosition(ele).y - fixPx
  window.scroll({ top: top, left: 0, behavior: 'smooth' })
}

const assetsOnClick = (e: Event) => {
  const target = e.currentTarget as HTMLElement
  const key = target.dataset.slug
  const type = target.dataset.type
  const item = mediaList.value.find((v: any) => v.key == key || v.slug == key)
  if (!item) return
  type === 'photo'
    ? openLightboxImage(item)
    : openLightboxVideo(item)
}

const addAssetsClickHandler = () => {
  if (typeof document === 'undefined') return
  Object.values(
    document.getElementsByClassName('card-asset')
  ).forEach((v: any) => {
    v.addEventListener('click', assetsOnClick)
  })

  Object.values(
    document.getElementsByClassName('card-video')
  ).forEach((v: any) => {
    v.addEventListener('click', assetsOnClick)
  })
}

const removeAssetsClickHandler = () => {
  if (typeof document === 'undefined') return
  Object.values(
    document.getElementsByClassName('card-asset')
  ).forEach((v: any) => {
    v.removeEventListener('click', assetsOnClick)
  })

  Object.values(
    document.getElementsByClassName('card-video')
  ).forEach((v: any) => {
    v.removeEventListener('click', assetsOnClick)
  })
}

onMounted(() => {
  updateScreenWidth()
  if (typeof window !== 'undefined') {
    window.addEventListener('resize', updateScreenWidth)
  }
  getData()
})

onUnmounted(() => {
  if (typeof window !== 'undefined') {
    window.removeEventListener('resize', updateScreenWidth)
  }
  removeAssetsClickHandler()
})
</script>

<style lang="scss" scoped>
.row {
  --bs-gutter-x: 16px;
  --bs-gutter-y: 0;
  display: flex;
  flex-wrap: wrap;
  margin-top: calc(var(--bs-gutter-y)*-1);
  margin-right: calc(var(--bs-gutter-x)*-0.5);
  margin-left: calc(var(--bs-gutter-x)*-0.5)
}

.row>* {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  padding-right: calc(var(--bs-gutter-x)*0.5);
  padding-left: calc(var(--bs-gutter-x)*0.5);
  margin-top: var(--bs-gutter-y)
}

.col {
  flex: 1 0 0%
}

.row-cols-1>* {
  flex: 0 0 auto;
  width: 100%
}

.row-cols-2>* {
  flex: 0 0 auto;
  width: 50%
}

.row-cols-3>* {
  flex: 0 0 auto;
  width: 33.3333333333%
}

.row-cols-4>* {
  flex: 0 0 auto;
  width: 25%
}

.row-cols-5>* {
  flex: 0 0 auto;
  width: 20%
}

.row-cols-6>* {
  flex: 0 0 auto;
  width: 16.6666666667%
}

.mt-10 {
  margin-top: 40px!important
}

@media (min-width: 768px) {
  .mt-md-12 {
    margin-top: 48px!important
  }
}

.card-carousel-multi-row {
  position: relative;
}

@media (max-width: 767.98px) {
  .card-carousel-multi-row__wrapper {
    padding-left: 0;
    padding-right: 0;
  }
}

.card-carousel-multi-row .row {
  --bs-gutter-x: 16px;
  --bs-gutter-y: 32px;
}

@media (max-width: 767.98px) {
  .card-carousel-multi-row .row {
    --bs-gutter-x: 8px;
    --bs-gutter-y: 28px;
  }
}

.card-carousel-multi-row__title {
  color: #0032A0;
  margin-bottom: 24px;
}

@media (max-width: 767.98px) {
  .card-carousel-multi-row__title {
    margin-bottom: 12px;
  }
}
</style>
